package Java面试周阳.阻塞队列.顺序打印;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ShareResource {
    // A 1   B 2   c 3
    private int number = 1;

    // 创建一个重入锁
    private Lock lock = new ReentrantLock();

    // 这三个相当于备用钥匙
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

    public void print5() {
        lock.lock();
        try {
            // 判断
            while (number != 1) {
                // 不等于1，需要等待
                condition1.await();
            }

            // 干活
            for(int i=0; i<5; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + number + "\t" + i);
            }

            // 唤醒（打印完后需要通知B线程执行）
            number = 2;
            // 通知2号打印
            condition2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void print10() {
        lock.lock();
        try {
            // 判断
            while (number != 2) {
                // 不等于2，需要等待
                condition1.await();
            }

            // 干活
            for(int i=0; i<10; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + number + "\t" + i);
            }

            // 唤醒（打印完后需要通知C线程执行）
            number = 3;
            // 通知3号打印
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void print15() {
        lock.lock();
        try {
            // 判断
            while (number != 3) {
                // 不等于2，需要等待
                condition1.await();
            }

            // 干活
            for(int i=0; i<15; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + number + "\t" + i);
            }

            // 唤醒（打印完后需要通知A线程执行）
            number = 1;
            // 通知1号打印
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
